package my_jwt

import (
	"github.com/dgrijalva/jwt-go"
	"time"
)

// 使用工厂创建一个 JWT 结构体
func CreateMyJWTV2(signKey string) *JwtSign {
	if len(signKey) <= 0 {
		signKey = "wwt-gin-api_model"
	}
	return &JwtSign{
		[]byte(signKey),
	}
}

// 定义一个 JWT验签 结构体
type JwtSignV2 struct {
	SigningKey []byte
}

// CreateToken 生成一个token
func (j *JwtSign) CreateTokenV2(claims CustomClaimsV2) (string, error) {
	// 生成jwt格式的header、claims 部分
	tokenPartA := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	// 继续添加秘钥值，生成最后一部分
	return tokenPartA.SignedString(j.SigningKey)
}

// 解析Token
func (j *JwtSign) ParseTokenV2(tokenString string) (*CustomClaimsV2, error) {
	token, _ := jwt.ParseWithClaims(tokenString, &CustomClaimsV2{}, func(token *jwt.Token) (interface{}, error) {
		return j.SigningKey, nil
	})
	if claims, ok := token.Claims.(*CustomClaimsV2); ok {
		return claims, nil
	}
	return nil, nil
	//	if token == nil {
	//		return nil, errors.New(my_errors.ErrorsTokenInvalid)
	//	}
	//	if err != nil {
	//		var ve *jwt.ValidationError
	//		if errors.As(err, &ve) {
	//			if ve.Errors&jwt.ValidationErrorMalformed != 0 {
	//				return nil, errors.New(my_errors.ErrorsTokenMalFormed)
	//			} else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 {
	//				return nil, errors.New(my_errors.ErrorsTokenNotActiveYet)
	//			} else if ve.Errors&jwt.ValidationErrorExpired != 0 {
	//				// 如果 TokenExpired ,只是过期（格式都正确），我们认为他是有效的，接下可以允许刷新操作
	//				token.Valid = true
	//				goto labelHere
	//			} else {
	//				return nil, errors.New(my_errors.ErrorsTokenInvalid)
	//			}
	//		}
	//	}
	//labelHere:
	//	if claims, ok := token.Claims.(*CustomClaimsV2); ok && token.Valid {
	//		return claims, nil
	//	} else {
	//		return nil, errors.New(my_errors.ErrorsTokenInvalid)
	//	}
}

// 更新token
func (j *JwtSign) RefreshTokenV2(tokenString string, extraAddSeconds int64) (string, error) {

	if CustomClaimsV2, err := j.ParseTokenV2(tokenString); err == nil {
		CustomClaimsV2.ExpiresAt = time.Now().Unix() + extraAddSeconds
		return j.CreateTokenV2(*CustomClaimsV2)
	} else {
		return "", err
	}
}
